//定向测试
class npu_dotp_test extends npu_base_test;
  `uvm_component_utils(npu_dotp_test)

  function new(string name = "npu_dotp_test", uvm_component parent);
    super.new(name, parent);
  endfunction

  virtual task run_phase(uvm_phase phase);
    npu_sequence seq;
    phase.raise_objection(this);

    // 初始化内存
    tb_top.dut.u_top.u_bram.mem[100] = 32'h00010002;  // a[0]=1, a[1]=2
    tb_top.dut.u_top.u_bram.mem[101] = 32'h00030004;  // b[0]=3, b[1]=4
    tb_top.dut.u_top.u_bram.mem[200] = 32'd0;         // dst

    // 配置 NPU
    write_reg(32'h1000_0000, 16'd2 << 16 | 1);  // len=2, start
    write_reg(32'h1000_0010, 32'h0000_0190);    // src_a = &a[0]
    write_reg(32'h1000_0014, 32'h0000_01A0);    // src_b = &b[0]
    write_reg(32'h1000_0018, 32'h0000_0320);    // dst

    // 等待完成
    wait_for_done();

    // 检查结果
    if (read_mem(200) !== 32'd11)  // 1*3 + 2*4 = 11
      `uvm_error("TEST", $sformatf("Expected 11, got %0d", read_mem(200)))
    else
      `uvm_info("TEST", "Dot product + ReLU passed!", UVM_LOW)

    phase.drop_objection(this);
  endtask

  task write_reg(logic [31:0] addr, logic [31:0] data);
    @(posedge tb_top.clk);
    tb_top.vif.mem_req   <= 1;
    tb_top.vif.mem_we    <= 1;
    tb_top.vif.mem_addr  <= addr;
    tb_top.vif.mem_wdata <= data;
    @(posedge tb_top.vif.mem_ack);
    tb_top.vif.mem_req   <= 0;
  endtask

  task wait_for_done();
    logic [31:0] ctrl;
    do begin
      ctrl = read_reg(32'h1000_0000);
      @(posedge tb_top.clk);
    end while (!ctrl[1]);
  endtask
endclass